package org.erikaredmark.monkeyshines.background; import java.awt.Graphics2D; import java.awt.image.BufferedImage; /** * * Represents a full, 640x400 background that is displayed taking up the entire window. These backgrounds are capable of * being very finely detailed, to the point of being substituted as scenery if so desired. They can be created from a single * 640x400 piece (the full background) or created from a Pattern (which is a smaller image that will be tiled onto * a 640x400 context) * <p/> * Instances of this class are immutable. System should create one instance per full background and instances are accessible * via {@code WorldResource} * * @author Erika Redmark * */ public class FullBackground extends Background { // 640x400 private final BufferedImage background; private final int id; private final boolean isPattern; private FullBackground(final BufferedImage background, int id, boolean isPattern) { if (background.getWidth() != 640 || background.getHeight() != 400) { throw new IllegalArgumentException("Backgrounds MUST be 640x480. Only patterns may be variable sizes."); } this.background = background; this.id = id; this.isPattern = isPattern; } /** * * Creates a basic full background. The background MUST be 640x400 * * @param background * the background * * @param id * the id of this background from the graphics resource. Required for encoding * algorithms to properly save instances * * @return * instance of this object * * @throws IllegalArgumentException * if the background is not 640x400 * */ public static FullBackground of(final BufferedImage background, int id) { return new FullBackground(background, id, false); } /** * * This classic background type (ppat resource) from the original Monkey Shines. Represents a variable * size pattern that will be tiled onto the destination. Creates a full background by tiling the pattern * onto a 640x480 context. * * @param ppat * the pattern to use * * @param id * the id of this background from the graphics resource. Required for encoding * algorithms to properly save instances * * @return * instance of this object * * @throws IllegalArgumentException * if the background is bigger than 640x400 * */ public static FullBackground fromPattern(final BufferedImage ppat, int id) { // We tile 640 / width. If there is any remainder, then we did NOT hit the edge // properly and must tile once more (albeit the last tile will only tile partway) int width = ppat.getWidth(); int height = ppat.getHeight(); int tileX = 640 / width + ( 640 % width != 0 ? 1 : 0); if (tileX == 0) throw new IllegalArgumentException("Width " + width + " too large for pattern: must be less than 640"); int tileY = 400 / height + ( 400 % height != 0 ? 1 : 0); if (tileY == 0) throw new IllegalArgumentException("Height " + height + " too large for pattern: must be less than 400"); BufferedImage background = new BufferedImage(640, 400, ppat.getType() ); Graphics2D graphics = background.createGraphics(); try { // Start with Y: for each ROW for (int j = 0; j < tileY; j++) { // For each COLUMN for (int i = 0; i < tileX; i++) { int dx = i * width, dy = j * height; graphics.drawImage( ppat, dx, dy, dx + width, dy + height, 0, 0, width, height, null); } } } finally { graphics.dispose(); } return new FullBackground(background, id, true); } @Override public void draw(Graphics2D g2d) { g2d.drawImage(background, 0, 0, 640, 400, 0, 0, 640, 400, null); } /** * * Intended for encoder algorithms. Returns the id that this background or pattern is * stored as. * */ public int getId() { return id; } /** * * Intended for encoder algorithms. Returns whether this background was created from a pattern or * as a full background. * */ public boolean isPattern() { return isPattern; } /** * * Returns the raw background as an image. Intended only for certain editor operations. * * @return * */ public BufferedImage getRawImage() { return background; } }